Django documentation

Using generic views

Writing Web applications can be monotonous, because we repeat certain patterns again and again. In Django, the most common of these patterns have been abstracted into "generic views" that let you quickly provide common views of an object without actually needing to write any views.

Django's generic views contain the following:

  • A set of views for doing list/detail interfaces (for example, Django's documentation index and detail pages).
  • A set of views for year/month/day archive pages and associated detail and "latest" pages (for example, the Django weblog's year, month, day, detail, and latest pages).
  • A set of views for creating, editing, and deleting objects.

All of these views are used by creating configuration dictionaries in your URLconf files and passing those dictionaries as the third member of the URLconf tuple. For example, here's the URLconf for the simple weblog app that drives the blog on djangoproject.com:

from django.conf.urls.defaults import *

info_dict = {
    'app_label': 'blog',
    'module_name': 'entries',
    'date_field': 'pub_date',
}

urlpatterns = patterns('django.views.generic.date_based',
   (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>\w+)/$', 'object_detail', dict(info_dict, slug_field='slug')),
   (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/$',               'archive_day',   info_dict),
   (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$',                                'archive_month', info_dict),
   (r'^(?P<year>\d{4})/$',                                                    'archive_year',  info_dict),
   (r'^/?$',                                                                  'archive_index', info_dict),
)

As you can see, this URLconf defines a few options in info_dict that tell the generic view which model to use (blog.entries in this case), as well as some extra information.

Documentation of each generic view follows, along with a list of all keyword arguments that a generic view expects. Remember that as in the example above, arguments may either come from the URL pattern (as month, day, year, etc. do above) or from the additional-information dictionary (as for app_label, module_name, etc.).

Most of the generic views that follow require the app_label and module_name keys. These values are easiest to explain through example:

>>> from django.models.blog import entries

In the above line, blog is the app_label (the name of the file that holds all your model definitions) and entries is the module_name (either a pluralized, lowercased version of the model class name, or the value of the module_name option of your model). In the docs below, these keys will not be repeated, but each generic view requires them.

Using "simple" generic views

The django.views.generic.simple module contains simple views to handle a couple of common cases: rendering a template when no view logic is needed, and issuing a redirect. These views are:

direct_to_template

Renders a given template, passing it a {{ params }} template variable, which is a dictionary of the parameters captured in the URL. This requires the template argument.

For example, given the following URL patterns:

urlpatterns = patterns('django.views.generic.simple',
    (r'^foo/$',             'direct_to_template', {'template': 'foo_index'}),
    (r'^foo/(?P<id>\d+)/$', 'direct_to_template', {'template': 'foo_detail'}),
)

... a request to /foo/ would cause the foo_index template to be rendered, and a request to /foo/15/ would cause the foo_detail template to be rendered with a context variable {{ params.id }} that is set to 15.

redirect_to

Issue a redirect to a given URL.

The given URL may contain dict-style string formatting, which will be interpolated against the params in the URL. For example, to redirect from /foo/<id>/ to /bar/<id>/, you could use the following urlpattern:

urlpatterns = patterns('django.views.generic.simple',
    ('^foo/(?p<id>\d+)/$', 'redirect_to', {'url' : '/bar/%(id)s/'}),
)

If the given URL is None, an HttpResponseGone (410) will be issued.

Using date-based generic views

Date-based generic views (in the module django.views.generic.date_based) feature six functions for dealing with date-based data. Besides app_label and module_name, all date-based generic views require that the date_field argument be passed to them. This is the name of the field that stores the date the objects should key off of.

Additionally, all date-based generic views have the following optional arguments:

Argument Description
template_name Overrides the default template name used for the view.
extra_lookup_kwargs A dictionary of extra lookup parameters (see the database API docs).
extra_context A dictionary of extra data to put into the template's context.

The date-based generic functions are:

archive_index

A top-level index page showing the "latest" objects. Has an optional argument, num_latest, which is the number of items to display on the page (defaults to 15).

Uses the template app_label/module_name_archive by default.

Has the following template context:

date_list
List of years with objects
latest
Latest objects by date
archive_year

Yearly archive. Requires that the year argument be present in the URL pattern.

Uses the template app_label/module_name_archive_year by default.

Has the following template context:

date_list
List of months in the given year with objects
year
The given year (an integer)
archive_month

Monthly archive. Requires that year and month arguments be given. You can pass the additional option month_format if you'd like to change the way months are specified in the URL.

month_format is a format string in the same syntax accepted by Python's time.strftime. (See the strftime docs.) It's set to "%b" by default, which is a three-letter month abbreviation. To change it to use numbers, use "%m".

Uses the template app_label/module_name_archive_month by default.

Has the following template context:

month
The given month (a datetime.datetime object)
object_list
List of objects published in the given month
archive_day

Daily archive. Requires that year, month, and day arguments be given.

As in archive_month, you can pass an optional month_format. You can also pass day_format, which defaults to "%d" (day of the month as a decimal number, 1-31).

Uses the template app_label/module_name_archive_day by default.

Has the following template context:

object_list
List of objects published this day
day
The given day (a datetime.datetime object)
previous_day
The previous day (a datetime.datetime object)
next_day
The next day (a datetime.datetime object), or None if the given day is today
archive_today
List of objects for today. Exactly the same as archive_day, except the year/month/day arguments are not given, and today's date is used instead.
object_detail

Individual object page. Requires year/month/day arguments like archive_day. This function can be used with two types of URLs: either /year/month/day/slug/ or /year/month/day/object_id/.

If you're using the slug-style URLs, you'll need to have a slug item in your URLconf, and you'll need to pass a slug_field key in your info dictionary to indicate the name of the slug field.

If your using the object_id-style URLs, you'll just need to give the URL pattern an object_id field.

You can also pass the template_name_field argument to indicate that the the object stores the name of its template in a field on the object itself.

As in archive_day, object_detail takes optional month_format and day_format parameters.

Using list/detail generic views

The list-detail generic-view framework (in the django.views.generic.list_detail module) is similar to the date-based one, except the former simply has two views: a list of objects and an individual object page.

All these views take the same three optional arguments as the date-based ones -- and, clearly, they don't accept the date_field argument.

Individual views are:

object_list

List of objects.

Takes the following optional arguments:

Argument Description
paginate_by If set to an integer, the view will paginate objects with paginate_by objects per page. The view will expect a page GET param with the (zero-indexed) page number.
allow_empty If False and there are no objects to display, the view will raise a 404 instead of displaying an empty index page. False is default.

Uses the template app_label/module_name_list by default.

Has the following template context:

object_list
List of objects
is_paginated
Are the results paginated? Either True or False

If the results are paginated, the context will have some extra variables:

results_per_page
Number of objects per page
has_next
Is there a next page?
has_previous
Is there a previous page?
page
The current page number
next
The next page number
previous
The previous page
pages
Number of pages total
hits
Total number of objects
object_detail
Object detail page. This works like and takes the same arguments as the date-based object_detail above, except this one, obviously, does not take the year/month/day arguments.

Using create/update/delete generic views

The django.views.generic.create_update module contains a set of functions for creating, editing and deleting objects. These views take the same global arguments as the above sets of generic views. They also have a login_required argument which, if True, requires the user to be logged in to have access to the page. (login_required defaults to False.)

The create/update/delete views are:

create_object

Create a new object. Has an extra optional argument, post_save_redirect, which is a URL to which the view will redirect after saving the object. It defaults to object.get_absolute_url().

post_save_redirect may contain dictionary string formatting, which will be interpolated against the object's field attributes. For example, you could use post_save_redirect="/polls/%(slug)s/".

Uses the template app_label/module_name_form by default. This is the same template as the update_object view below. Your template can tell the different by the presence or absence of {{ object }} in the context.

Has the following template context:

form
The form wrapper for the object

Note

See the manipulator and formfield documentation for more information about using form wrappers in templates.

update_object

Edit an existing object. Has the same extra slug/ID parameters as list_detail.object_detail does (see above), and the same post_save_redirect as create_object does.

Uses the template app_label/module_name_form by default.

Has the following template context:

form
The form wrapper for the object
object
The original object being edited
delete_object

Delete an existing object. The given object will only actually be deleted if the request method is POST. If this view is fetched with GET, it will display a confirmation page that should contain a form that POSTs to the same URL.

You must provide the post_delete_redirect argument to this function, so that the view knows where to go after the object is deleted.

If fetched with GET, it uses the template app_label/module_name_confirm_delete by default. It uses no template if POSTed -- it simply deletes the object and redirects.

Has the following template context:

object
The object about to be deleted

Comments

Max July 25, 2005 at 2:13 a.m.

There are a lot of references to slugs here, but is there any documentation about that "slug-style-url"? In fact, what is a slug?

Edgars July 25, 2005 at 3:22 a.m.

Max, for example http://myserver/2005/jul/25/my_test_post... - my_test_post is a slug.

sway July 25, 2005 at 2:03 p.m.

It seems like generic.viewDispatcher would be more accurate to what's really happening here.

xtian July 26, 2005 at 7:32 a.m.

Man, you guys needed to document this bit earlier - this is the stuff that really makes this a RAD-style framework. Although I guess it would all be a bit academic without the DB api and the templating language.

Looks brilliant - I'm looking forward to having a bit more of a play with this.

Randy July 30, 2005 at 1:55 p.m.

I would like to see more examples, of how to use these generic views. Like xtian mentioned above, this is very powerful stuff. I think it merits more explanation and examples.

Grzegorz July 31, 2005 at 8:37 a.m.

hello i think to there should be more examples about generic view, this looks very interesting. The good example will be e.g. how it was used on the pages that runs on django (i mean lawrence.com...)

maurycy July 31, 2005 at 5:55 p.m.

Grzegorz, take a look at djangoproject.com sources. They're freely available in the subversion repository.

ianm August 17, 2005 at 11:08 a.m.

Matt Croydon posted a nice tutorial on his blog:

http://www.postneo.com/2005/08/17/django...

pedro August 25, 2005 at 12:17 p.m.

Is there a way to use this login_required argument to lock the entire site (views and CRUD)?

Luke September 16, 2005 at 6:32 p.m.

You don't have to use URLconf to use generic views. You can also write your own (very short) view functions which do something with the request first, then call the generic view function directly. This allows the parameters that generic views accept to be generated dynamically.

Scott Pierce September 19, 2005 at 11:58 p.m.

for detail/list generic views, you might want to throw in the fact that these views have more optional keyword arguments than shown above:

paginate_by, allow_empty, template_name, extra_lookup_kwargs, extra_context. An example of extra_lookup_kwargs would likely be helpful.

Post a comment

Note: Please only use the comments for questions/critcisms/suggestions on the docs; if you experience errors please file a ticket, ask in the IRC channel, or post to the django-users list. Comments will be periodically reviewed, integrated into the documentation proper, and removed.

Your name:

Comment: